/* Copyright (c) 2022 渝州大数据实验室
 *
 * Lanius is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 *     http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.yzbdl.lanius.orchestrate.serv.utils;

import cn.hutool.core.codec.Base64Encoder;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.HttpStatus;
import org.yzbdl.lanius.orchestrate.common.exception.runtime.BusinessException;
import org.yzbdl.lanius.orchestrate.common.utils.MessageUtil;

import java.io.*;
import java.util.Map;
import java.util.Objects;
import java.util.zip.GZIPInputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

/**
 * Http请求工具类
 *
 * @author jinchunzhao@yzbdl.ac.cn
 * @date 2022-04-21 9:57
 */
public class HttpUtil {

	private static final String CHARACTER_ENCODING = "UTF-8";

	private static final String AUTH = "Authorization";

	/**
	 * 中转站
	 * <p>
	 *     获取第三发接口的response字节流，输出到本地接口的response中
	 * </p>
	 *
	 * @param response
	 *        response
	 * @param url
	 *        请求URL
	 * @param headers
	 *        消息头
	 */
	public static void transStationResponseHttpGet(HttpServletResponse response, String url, Map<String, Object> headers){
		// 创建一个HTTP客户端
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
		// 创建一个get请求
		HttpGet httpGet = new HttpGet(url);

		for (String key : headers.keySet()) {
			httpGet.setHeader(key, headers.get(key).toString());
		}

		ServletOutputStream out = null;
		BufferedOutputStream bos = null;
		InputStream inputStream = null;
		try {
			// 执行第三方接口的请求
			HttpResponse httpResponse = httpClient.execute(httpGet);
			// 拿到响应数据
			HttpEntity entity = httpResponse.getEntity();
			// 获取contentType
			Header contentType = entity.getContentType();
			inputStream = entity.getContent();

			// 设置编码
			response.setCharacterEncoding(CHARACTER_ENCODING);
			//  设置ContentType
			response.setContentType(contentType.getValue());
			byte[] bytes = new byte[inputStream.available()];

			out = response.getOutputStream();
			bos = new BufferedOutputStream(out);
			int n;
			while ((n = inputStream.read(bytes)) != -1){
				bos.write(bytes,0,n);
			}
			bos.flush();

		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			// 执行关闭流操作
			try {
				if (Objects.nonNull(bos)){
					bos.close();
				}
				if (Objects.nonNull(out)){
					out.close();
				}
				if (Objects.nonNull(inputStream)){
					inputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * 中转站
	 * <p>
	 *     获取第三发接口的图片response流，输出到本地接口的中生成Base64
	 * </p>
	 *
	 * @param url
	 *        请求URL
	 * @param headers
	 *        消息头
	 * @return base64字符串
	 */
	public static String getImageBase64FromResponse(String url, Map<String, Object> headers){
		// 创建一个HTTP客户端
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
		// 创建一个get请求
		HttpGet httpGet = new HttpGet(url);

		for (String key : headers.keySet()) {
			httpGet.setHeader(key, headers.get(key).toString());
		}

		InputStream inputStream = null;
		ByteArrayOutputStream outputStream = null;
		String base64Str = null;
		try {
			// 执行第三方接口的请求
			HttpResponse httpResponse = httpClient.execute(httpGet);
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			if (!Objects.equals(statusCode, HttpStatus.OK.value())){
				throw new BusinessException(MessageUtil.get("task.instance.image_not_found"));
			}
			// 拿到响应数据
			HttpEntity entity = httpResponse.getEntity();
			inputStream = entity.getContent();
			outputStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[inputStream.available()];
			int len;
			// 读取图片
			while ((len = inputStream.read(buffer)) > 0){
				outputStream.write(buffer,0,len);
			}
			outputStream.flush();
			// 转换为base64
			base64Str = Base64Encoder.encode(outputStream.toByteArray());

		} catch (IOException e) {
			throw new BusinessException(MessageUtil.get("task.instance.image_not_found"));
		}finally {
			// 执行关闭流操作
			try {
				if (Objects.nonNull(inputStream)){
					inputStream.close();
				}
				if (Objects.nonNull(outputStream)){
					outputStream.close();
				}
				if (Objects.nonNull(inputStream)){
					inputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		// 拼接前缀
		return "data:image/jpg;base64,"+base64Str;
	}

	/**
	 * 解析base64字符串
	 *
	 * @param content
	 *        base64字符串
	 * @return
	 *        解析后的字符串
	 * @throws IOException
	 *         IOException
	 */
	public static String decodeBase64ZippedString(String content) throws IOException {
		if (content != null && !content.isEmpty()) {
			new StringWriter();
			byte[] bytes64 = Base64.decodeBase64(content.getBytes());
			ByteArrayInputStream zip = new ByteArrayInputStream(bytes64);
			GZIPInputStream unzip = null;
			InputStreamReader reader = null;
			BufferedInputStream in = null;

			StringWriter writer;
			try {
				unzip = new GZIPInputStream(zip, 8192);
				in = new BufferedInputStream(unzip, 8192);
				reader = new InputStreamReader(in, "UTF-8");
				writer = new StringWriter();
				char[] buff = new char[8192];
				boolean var8 = false;

				int length;
				while((length = reader.read(buff)) > 0) {
					writer.write(buff, 0, length);
				}
			} finally {
				if (reader != null) {
					try {
						reader.close();
					} catch (IOException var20) {
					}
				}

				if (in != null) {
					try {
						in.close();
					} catch (IOException var19) {
					}
				}

				if (unzip != null) {
					try {
						unzip.close();
					} catch (IOException var18) {
					}
				}

			}

			return writer.toString();
		} else {
			return "";
		}
	}

}
